package wili.attrMapping._user.b1;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import wili.a.Refs;
import wili.attrMapping.core.Att9;
import wili.attrMapping.core.Atts;
import wili.attrMapping.core.AttsDefine;
import wili.attrMapping.core.AttsFile;
import wili.attrMapping.core.JsonUserConf;
import wili.attrMapping.file.JsonFile;
import wili.c.Ca;
import wili.json.JsonLeaf;
import wili.json.JsonNode;
import wili.json.JsonObj;

/**
 * @author weila 2022年10月3日
 */
public abstract class B1JsonUserConf extends JsonUserConf {
	static final String FORMULA = "formula";

	public B1JsonUserConf(String ruleFile, AttsDefine def) {
		super(ruleFile, def);
	}

	static int opt = 1;

	@Override
	public List<File> getOldFiles() {
		if (opt == 1) {//purchase doc 
			File dir = new File(DemoDIR, "p");
			return Arrays.asList(dir.listFiles(f -> f.getName().endsWith(".json")));
		} else if (opt == 2) {//sales doc.
			File dir = new File(DemoDIR, "s");
			return Arrays.asList(dir.listFiles(f -> f.getName().endsWith(".json")));
		} else if (opt == 3) {// middle
			File dir = new File(DemoDIR, "xml");
			return Arrays.asList(dir.listFiles(f -> f.getName().endsWith(".xml")));
		} else {// 简化后测试
			File dir = new File(DemoDIR, "a");
			return Arrays.asList(dir.listFiles(f -> f.getName().endsWith(".json")));
		}
	}

	private List<AttsFile> newFiles;

	@Override
	public List<AttsFile> getNewAttsFiles() {
		if (newFiles != null)
			return newFiles;
		if (opt == 1) {
			File dir = new File(DemoDIR, "p/p2");
			File[] ff = dir.listFiles(f -> f.getName().endsWith(".json"));
			return newFiles = Stream.of(ff).map(file -> this.attsFileOf(file)).collect(Collectors.toList());
		} else if (opt == 2) {// middle
			File dir = new File(DemoDIR, "s/s2");
			File[] ff = dir.listFiles(f -> f.getName().endsWith(".json"));
			return newFiles = Stream.of(ff).map(file -> this.attsFileOf(file)).collect(Collectors.toList());
		} else if (opt == 3) {
			File dir = new File(DemoDIR, "x");
			File[] ff = dir.listFiles(f -> f.getName().endsWith(".xml"));
			return newFiles = Stream.of(ff).map(file -> this.attsFileOf(file)).collect(Collectors.toList());
		} else {
			File dir = new File(DemoDIR, "a/a2");
			File[] ff = dir.listFiles(f -> f.getName().endsWith(".json"));
			return newFiles = Stream.of(ff).map(file -> this.attsFileOf(file)).collect(Collectors.toList());
		}
	}

	/**
	 * 查找旧属性集
	 */
	@Override
	public List<Atts> findOldAttsList(AttsDefine def, AttsFile file_) {
		Att9.usage("查找旧属性");
		JsonFile file = (JsonFile) file_;
		List<Atts> ret = new ArrayList<>();
		List<JsonNode> oldObjList = file.findNodesByPath(def.objName);
		for (int i = 0; i < oldObjList.size(); i++) {
			JsonNode obj = oldObjList.get(i);

			if (!(obj instanceof JsonObj))
				continue;
			JsonObj oldObj = (JsonObj) obj;
			JsonLeaf guid = obj.dad.son(def.keyName);
			if (guid == null)
				continue;
			List<JsonNode> attNodes = oldObj.getAtts(true, def.attNames.toArray(new String[def.attNames.size()]));// 取得对象的若干属性
			Atts atts = this.createAtts(file, guid.stringValue, obj, false);
			for (int j = 0; j < attNodes.size(); j++) {
				JsonNode nod = attNodes.get(j);
				Refs.now();//
				atts.addAtt(nod.attName, nod.stringValue);
			}
			ret.add(atts);
		}
		return ret;
	}

	@Override
	public List<Atts> findNewAttsList(Atts oldAtts) {
		Att9.usage("查找新属性");//
		Ca.asert(!oldAtts.isNewAtts, "");
		String fromKind = oldAtts.getKind();
		List<Atts> all_newAttsList = new ArrayList<>();
		List<AttsFile> newFiles = this.getNewAttsFiles();
		if (oldAtts.newAttsList == null) {
			// 找到旧属性集的key, 通过key找到新属性、关联之。
			String key = oldAtts.key;
			f1: for (int j = 0; j < newFiles.size(); j++) {
				AttsFile newFile = newFiles.get(j);
				JsonFile newFile2 = (JsonFile) newFile;
				List<JsonLeaf> ids = newFile2.root.findLeafs(attDefine.keyName, key, -1);
				if (!ids.isEmpty()) {
					for (int k = 0; k < ids.size(); k++) {
						JsonLeaf idLeaf = ids.get(k);
						JsonLeaf newLeaf = idLeaf.dad.son(attDefine.objName);
						if (newLeaf == null)
							continue;
						Atts newAtts = this.createAtts(newFile, key, newLeaf, true);
						if (!fromKind.equals(newAtts.getKind()))
							continue f1;
						oldAtts.addNewAtt(newAtts);// relates to old atts.
					}
					Ca.pause();
				}
			}
		}
		if (oldAtts.newAttsList != null) {
			all_newAttsList.addAll(oldAtts.newAttsList);
		}
		return all_newAttsList;
	}

	public String replaceFileContent_atLast(String st) {
		String st2 = st;
		{// eg. {/DocEntry} eq null ~>[undefined, null].includes({/DocEntry})
		 // String f = "\\{/DocEntry\\} (eq|===) null\\}|\\$\\{/DocEntry\\} === null";
			String regSt = "(\\$?)\\{/DocEntry\\}\\s+(eq|===)\\s+null";
			// String t = "[undefined, null].includes(\\$\\{/DocEntry\\})";
			String includFunSt = "[undefined, null].includes(\\$\\{/DocEntry\\})";
			st2 = st2.replaceAll(regSt, includFunSt);
			//
			regSt = regSt.replace("/DocEntry", "DocEntry");
			includFunSt = includFunSt.replace("/DocEntry", "DocEntry");
			st2 = st2.replaceAll(regSt, includFunSt);
		}
		return st2;
	}

	protected static String standValueLR(String val) {
		val = val.trim();
		if (val.matches("\\w+"))
			return val;
		String st = AttConst.placeholderOf(FORMULA);
		val = val.replace(st, "(" + st + ")");
		if (!val.startsWith("{="))
			val = "{=" + val + "}";
		return val;
	}

	@Override
	public abstract String genRuleOf_oldNewAtts(Atts oldAtts, Atts newAtts);
}
